home *** CD-ROM | disk | FTP | other *** search
/ NOVA - For the NeXT Workstation / NOVA - For the NeXT Workstation.iso / SourceCode / AdobeExamples / NX_Binary / Graphic.m < prev    next >
Encoding:
Text File  |  1992-12-19  |  13.2 KB  |  582 lines

  1.  
  2. /*
  3.  * (a)  (C) 1990 by Adobe Systems Incorporated. All rights reserved.
  4.  *
  5.  * (b)  If this Sample Code is distributed as part of the Display PostScript
  6.  *    System Software Development Kit from Adobe Systems Incorporated,
  7.  *    then this copy is designated as Development Software and its use is
  8.  *    subject to the terms of the License Agreement attached to such Kit.
  9.  *
  10.  * (c)  If this Sample Code is distributed independently, then the following
  11.  *    terms apply:
  12.  *
  13.  * (d)  This file may be freely copied and redistributed as long as:
  14.  *    1) Parts (a), (d), (e) and (f) continue to be included in the file,
  15.  *    2) If the file has been modified in any way, a notice of such
  16.  *      modification is conspicuously indicated.
  17.  *
  18.  * (e)  PostScript, Display PostScript, and Adobe are registered trademarks of
  19.  *    Adobe Systems Incorporated.
  20.  * 
  21.  * (f) THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO
  22.  *    CHANGE WITHOUT NOTICE, AND SHOULD NOT BE CONSTRUED
  23.  *    AS A COMMITMENT BY ADOBE SYSTEMS INCORPORATED.
  24.  *    ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY
  25.  *    OR LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO
  26.  *    WARRANTY OF ANY KIND (EXPRESS, IMPLIED OR STATUTORY)
  27.  *    WITH RESPECT TO THIS INFORMATION, AND EXPRESSLY
  28.  *    DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, 
  29.  *    FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT
  30.  *    OF THIRD PARTY RIGHTS.
  31.  */
  32.  
  33. /*
  34. *    Graphic.m
  35.  *
  36.  *    Version:    2.0
  37.  *    Author:    Ken Fromm
  38.  *    History:
  39.  *            03-07-91        Added this comment.
  40. */
  41.  
  42. #import "Graphic.h"
  43. #import "DrawingViewWraps.h"
  44. #import <appkit/defaults.h>
  45. #import <appkit/nextstd.h>
  46. #import <dpsclient/wraps.h>
  47.  
  48. void initGparms(GParms *gParms)
  49. {
  50.     gParms->path_type = STROKE;
  51.     gParms->color_type = GRAY;
  52.     gParms->gray =  NX_BLACK;
  53.     gParms->red = gParms->green = gParms->blue = NX_BLACK;
  54.     gParms->linewidth = 1;
  55.     gParms->miterlimit = 10;
  56.     gParms->linejoin = gParms->linecap = 0;
  57. }
  58.  
  59. @implementation Graphic : Object
  60.  
  61. + new
  62. {
  63.     self = [super new];
  64.     initGparms(&parms);
  65.     
  66.     return self;
  67. }
  68.  
  69. - free
  70. {
  71.     if (path.pts)
  72.         NX_FREE(path.pts);
  73.     if (path.ops)
  74.         NX_FREE(path.ops);
  75.  
  76.     return self;
  77. }
  78.  
  79. - installGparms:(const GParms *) gParm
  80. {
  81.     parms = *gParm;
  82.  
  83.     return self;
  84. }
  85.  
  86. - installUpath:(const UPath *) aUpath andBounds:(const NXRect *) aRect
  87. {
  88.     NX_MALLOC(path.pts, float, aUpath->num_pts+4);
  89.     NX_MALLOC(path.ops, char, aUpath->num_ops+1);
  90.  
  91.     bcopy(aUpath->pts, &path.pts[4], aUpath->num_pts * sizeof(float)/sizeof(char));
  92.     path.num_pts = aUpath->num_pts + 4;
  93.  
  94.     path.ops[0] = dps_ucache;
  95.     bcopy(aUpath->ops, &path.ops[1], aUpath->num_ops);
  96.     path.num_ops = aUpath->num_ops + 1;
  97.  
  98.  
  99.     bounds = *aRect;
  100.     path.pts[0] = bounds.origin.x;
  101.     path.pts[1] = bounds.origin.y;
  102.     path.pts[2] = bounds.origin.x + bounds.size.width;
  103.     path.pts[3] = bounds.origin.y + bounds.size.height;
  104.  
  105.     return self;
  106. }
  107.  
  108. - getBounds:(NXRect *)theRect
  109. {
  110.     *theRect = bounds;
  111.  
  112.     return self;
  113. }
  114.  
  115. /* Public routines. */
  116. - setPathType:(int) value
  117. {
  118.     parms.path_type = (unsigned char) value;
  119.  
  120.     return self;
  121. }
  122.  
  123. - (int)pathType
  124. {
  125.     return  (int)parms.path_type;
  126. }
  127.  
  128. - setLineWidth:(float) value
  129. {
  130.     parms.linewidth = value;
  131.  
  132.     return self;
  133. }
  134.  
  135. - (float)lineWidth
  136. {
  137.     return parms.linewidth;
  138. }
  139.  
  140. - setLineJoin:(int) value
  141. {
  142.     parms.linejoin = (unsigned char) value;
  143.  
  144.     return self;
  145. }
  146.  
  147. - (int)lineJoin
  148. {
  149.     return (int) parms.linejoin;
  150. }
  151.  
  152. - setLineCap:(int) value
  153. {
  154.     parms.linecap = (unsigned char) value;
  155.  
  156.     return self;
  157. }
  158.  
  159. - (int)lineCap
  160. {
  161.     return (int) parms.linecap;
  162. }
  163.  
  164. - setMiterLimit:(float) value
  165. {
  166.     parms.miterlimit = value;
  167.  
  168.     return self;
  169. }
  170.  
  171. - (float) miterLimit
  172. {
  173.     return parms.miterlimit;
  174. }
  175.  
  176. - (int) colorType
  177. {
  178.     return (int) parms.color_type;
  179. }
  180.  
  181. - setGray:(float) value
  182. {
  183.     parms.gray = value;
  184.     parms.color_type = GRAY;
  185.  
  186.     return self;
  187. }
  188.  
  189. - (float)gray
  190. {
  191.     return parms.gray;
  192. }
  193.  
  194. - setRGBColor:(int)r  : (int)g  :(int)b
  195. {
  196.     parms.red = r;
  197.     parms.green = g;
  198.     parms.blue = b;
  199.     parms.color_type = RGB;
  200.  
  201.     return self;
  202. }
  203.  
  204. - getRGBColor:(int *)r  : (int *)g  :(int *)b
  205. {
  206.     *r = parms.red;
  207.     *g = parms.green;
  208.     *b = parms.blue;
  209.  
  210.     return self;
  211. }
  212.  
  213. - setHGBColor:(int)h  :(int)s  :(int)b
  214. {
  215.     parms.red = h;
  216.     parms.green = s;
  217.     parms.blue = b;
  218.     parms.color_type = HSB;
  219.  
  220.     return self;
  221. }
  222.  
  223. - getHGBColor:(int *)h  :(int *)s  :(int *)b
  224. {
  225.     *h = parms.red;
  226.     *s = parms.green;
  227.     *b = parms.blue;
  228.  
  229.     return self;
  230. }
  231.  
  232. - setCMYKColor:(int)c  : (int)m :(int)y  :(int)k
  233. {
  234.     parms.red = c;
  235.     parms.green = m;
  236.     parms.blue = y;
  237.     parms.gray = k;
  238.     parms.color_type = CMYK;
  239.  
  240.     return self;
  241. }
  242.  
  243. - getCMYKColor:(int *)c  : (int *)m :(int *)y  :(int *)k
  244. {
  245.     *c = parms.red;
  246.     *m = parms.green;
  247.     *y = parms.blue;
  248.     *k = parms.gray;
  249.  
  250.     return self;
  251. }
  252.  
  253. /* Make this external so that DrawingView can use it. */
  254. void setGraphicState(GParms *curParms, GParms *objParms, int format)
  255. {
  256.     DPSContext    ctxt;
  257.     
  258.     ctxt = DPSGetCurrentContext();
  259.  
  260.     if (!curParms || objParms->linewidth != curParms->linewidth)
  261.     {
  262.         if (format == ABBR)
  263.             PSWSetlinewidth(objParms->linewidth);
  264.         else if (format == BOT)
  265.         {
  266.             DPSPrintf(ctxt, "\214");    
  267.             DPSWriteData(ctxt, &objParms->linewidth, sizeof(float));
  268.             DPSPrintf(ctxt, "\222\233");
  269.         }    
  270.         else
  271.             PSsetlinewidth(objParms->linewidth);
  272.     }
  273.     if (!curParms || objParms->linejoin != curParms->linejoin)
  274.     {
  275.         if (format == ABBR)
  276.             PSWSetlinejoin((int) objParms->linejoin);
  277.         else if (format == BOT)
  278.         {
  279.             DPSPrintf(ctxt, "\210");    
  280.             DPSWriteData(ctxt, &objParms->linejoin, sizeof(char));
  281.             DPSPrintf(ctxt, "\222\232");
  282.         }
  283.         else
  284.             PSsetlinejoin((int) objParms->linejoin);
  285.     }
  286.     if (!curParms || objParms->linecap != curParms->linecap)
  287.     {
  288.         if (format == ABBR)
  289.             PSWSetlinecap((int) objParms->linecap);
  290.         else if (format == BOT)
  291.         {
  292.             DPSPrintf(ctxt, "\210");    
  293.             DPSWriteData(ctxt, &objParms->linecap, sizeof(char));
  294.             DPSPrintf(ctxt, "\222\231");
  295.         }
  296.         else
  297.             PSsetlinecap((int) objParms->linecap);
  298.     }
  299.     if (!curParms || objParms->miterlimit != curParms->miterlimit)
  300.     {
  301.         if (format == ABBR)
  302.             PSWSetmiterlimit(objParms->miterlimit);
  303.         else
  304.             PSsetmiterlimit(objParms->miterlimit);
  305.     }
  306.  
  307.     switch (objParms->color_type)
  308.     {
  309.         case GRAY:
  310.             if (!curParms || objParms->gray != curParms->gray)
  311.             {
  312.                 if (format == ABBR)
  313.                     PSWSetgray(objParms->gray);
  314.                 else if (format == BOT)
  315.                 {
  316.                     DPSPrintf(ctxt, "\214");    
  317.                     DPSWriteData(ctxt, &objParms->gray, sizeof(float));
  318.                     DPSPrintf(ctxt, "\222\226");
  319.                 }    
  320.                 else
  321.                     PSsetgray(objParms->gray);
  322.             }
  323.             break;
  324.         case RGB:
  325.             if (!curParms || objParms->red != curParms->red ||
  326.                 objParms->green != curParms->green ||
  327.                 objParms->blue != curParms->blue)
  328.             {
  329.                 if (format == ABBR)
  330.                     PSWSetrgbcolor(objParms->red, objParms->green, objParms->blue);
  331.                 else if (format == BOT)
  332.                 {
  333.                     DPSPrintf(ctxt, "\214");    
  334.                     DPSWriteData(ctxt, &objParms->red, sizeof(float));
  335.                     DPSPrintf(ctxt, "\214");    
  336.                     DPSWriteData(ctxt, &objParms->green, sizeof(float));
  337.                     DPSPrintf(ctxt, "\214");    
  338.                     DPSWriteData(ctxt, &objParms->blue, sizeof(float));
  339.                     DPSPrintf(ctxt, "\222\235");
  340.                 }
  341.                 else
  342.                     PSsetrgbcolor(objParms->red, objParms->green, objParms->blue);
  343.             }
  344.             break;
  345.         case HSB:
  346.             if (!curParms || objParms->red != curParms->red ||
  347.                 objParms->green != curParms->green ||
  348.                 objParms->blue != curParms->blue)
  349.             {
  350.                 if (format == ABBR)
  351.                     PSWSethsbcolor(objParms->red, objParms->green, objParms->blue);
  352.                 else if (format == BOT)
  353.                 {
  354.                     DPSPrintf(ctxt, "\214");    
  355.                     DPSWriteData(ctxt, &objParms->red, sizeof(float));
  356.                     DPSPrintf(ctxt, "\214");    
  357.                     DPSWriteData(ctxt, &objParms->green, sizeof(float));
  358.                     DPSPrintf(ctxt, "\214");    
  359.                     DPSWriteData(ctxt, &objParms->blue, sizeof(float));
  360.                     DPSPrintf(ctxt, "\222\230");
  361.                 }
  362.                 else
  363.                     PSsethsbcolor(objParms->red, objParms->green, objParms->blue);
  364.             }
  365.             break;
  366.         case CMYK:
  367.             if (!curParms || objParms->red != curParms->red ||
  368.                 objParms->green != curParms->green ||
  369.                 objParms->blue != curParms->blue ||
  370.                 objParms->gray != curParms->gray)
  371.             {
  372.                 if (format == ABBR)
  373.                     PSWSetcmykcolor(objParms->red, objParms->green, objParms->blue,
  374.                     objParms->gray);
  375.                 else if (format == BOT)
  376.                 {
  377.                     DPSPrintf(ctxt, "\214");    
  378.                     DPSWriteData(ctxt, &objParms->red, sizeof(float));
  379.                     DPSPrintf(ctxt, "\214");    
  380.                     DPSWriteData(ctxt, &objParms->green, sizeof(float));
  381.                     DPSPrintf(ctxt, "\214");    
  382.                     DPSWriteData(ctxt, &objParms->blue, sizeof(float));
  383.                     DPSPrintf(ctxt, "\214");    
  384.                     DPSWriteData(ctxt, &objParms->gray, sizeof(float));
  385.                     DPSPrintf(ctxt, "\222\223");
  386.                 }
  387.                 else
  388.                     PSsetcmykcolor(objParms->red, objParms->green, objParms->blue,
  389.                     objParms->gray);
  390.             }
  391.             break;
  392.     }
  393.  
  394.     if (curParms)
  395.         *curParms = *objParms;
  396. }
  397.  
  398. /*
  399. *    Call the appropriate wrap to construct the path. Not the recommended
  400. *    approach to drawing  paths (user paths are). 
  401. */
  402. static void makeRedBook(UPath *aUpath, int format)
  403. {
  404.     int        i_op, i_pt;
  405.  
  406.     DPSContext    ctxt;
  407.     
  408.     ctxt = DPSGetCurrentContext();    
  409.  
  410.     /* Skip the ucache operator. */
  411.     i_pt = 4;
  412.     for (i_op = 1; i_op < aUpath->num_ops; i_op++)
  413.     {
  414.         switch (aUpath->ops[i_op])
  415.         {
  416.             case dps_moveto:
  417.                 if (format == ABBR)
  418.                     PSWMoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);                
  419.                 else if (format == BOT)
  420.                 {
  421.                     DPSPrintf(ctxt, "\214");    
  422.                     DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
  423.                     DPSPrintf(ctxt, "\214");    
  424.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
  425.                     DPSPrintf(ctxt, "\222\153");
  426.                 }    
  427.                 else
  428.                     PSmoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
  429.                 i_pt += 2;
  430.                 break;
  431.             case dps_rmoveto:
  432.                 if (format == ABBR)
  433.                     PSWRmoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
  434.                 else if (format == BOT)
  435.                 {
  436.                     DPSPrintf(ctxt, "\214");    
  437.                     DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
  438.                     DPSPrintf(ctxt, "\214");    
  439.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
  440.                     DPSPrintf(ctxt, "\222\206");
  441.                 }    
  442.                 else
  443.                     PSrmoveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
  444.                 i_pt += 2;
  445.                 break;
  446.             case dps_lineto:
  447.                 if (format == ABBR)
  448.                     PSWLineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
  449.                 else if (format == BOT)
  450.                 {
  451.                     DPSPrintf(ctxt, "\214");    
  452.                     DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
  453.                     DPSPrintf(ctxt, "\214");    
  454.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
  455.                     DPSPrintf(ctxt, "\222\143");
  456.                 }
  457.                 else
  458.                     PSlineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
  459.                 i_pt += 2;
  460.                 break;
  461.             case dps_rlineto:
  462.                 if (format == ABBR)
  463.                     PSWRlineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
  464.                 else if (format == BOT)
  465.                 {
  466.                     DPSPrintf(ctxt, "\214");    
  467.                     DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
  468.                     DPSPrintf(ctxt, "\214");    
  469.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
  470.                     DPSPrintf(ctxt, "\222\205");
  471.                 }
  472.                 else
  473.                     PSrlineto(aUpath->pts[i_pt], aUpath->pts[i_pt+1]);
  474.                 i_pt += 2;
  475.                 break;
  476.             case dps_curveto:
  477.                 if (format == ABBR)
  478.                     PSWCurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
  479.                         aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
  480.                         aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
  481.                 else if (format == BOT)
  482.                 {
  483.                     DPSPrintf(ctxt, "\214");    
  484.                     DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
  485.                     DPSPrintf(ctxt, "\214");    
  486.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
  487.                     DPSPrintf(ctxt, "\214");    
  488.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+ 2], sizeof(float));
  489.                     DPSPrintf(ctxt, "\214");    
  490.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+3], sizeof(float));
  491.                     DPSPrintf(ctxt, "\214");    
  492.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+4], sizeof(float));
  493.                     DPSPrintf(ctxt, "\214");    
  494.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+5], sizeof(float));
  495.  
  496.                     DPSPrintf(ctxt, "\222\053");
  497.                 }
  498.                 else
  499.                     PScurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
  500.                         aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
  501.                         aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
  502.                 i_pt += 6;
  503.                 break;
  504.             case dps_rcurveto:
  505.                 if (format == ABBR)
  506.                     PSWRcurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
  507.                         aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
  508.                         aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
  509.                 else if (format == BOT)
  510.                 {
  511.                     DPSPrintf(ctxt, "\214");    
  512.                     DPSWriteData(ctxt, &aUpath->pts[i_pt], sizeof(float));
  513.                     DPSPrintf(ctxt, "\214");    
  514.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+1], sizeof(float));
  515.                     DPSPrintf(ctxt, "\214");    
  516.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+ 2], sizeof(float));
  517.                     DPSPrintf(ctxt, "\214");    
  518.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+3], sizeof(float));
  519.                     DPSPrintf(ctxt, "\214");    
  520.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+4], sizeof(float));
  521.                     DPSPrintf(ctxt, "\214");    
  522.                     DPSWriteData(ctxt, &aUpath->pts[i_pt+5], sizeof(float));
  523.  
  524.                     DPSPrintf(ctxt, "\222\172");
  525.                 }
  526.                 else
  527.                     PSrcurveto(aUpath->pts[i_pt], aUpath->pts[i_pt+1],
  528.                         aUpath->pts[i_pt+2], aUpath->pts[i_pt+3],
  529.                         aUpath->pts[i_pt+4], aUpath->pts[i_pt+5]);
  530.                 i_pt += 6;
  531.                 break;
  532.             case dps_closepath:
  533.                 if (format == ABBR)
  534.                     PSWClosepath();
  535.                 else if (format == BOT)
  536.                     DPSPrintf(ctxt, "\222\026");
  537.                 else
  538.                     PSclosepath();
  539.                 break;
  540.         }
  541.     }
  542. }
  543.  
  544. /*
  545.  * Draws the graphic.
  546.  */
  547. - drawObject:(NXRect *) r  currentParms:(GParms *) gParms withFormat:(int) format
  548. {
  549.     DPSContext    ctxt;
  550.     
  551.     ctxt = DPSGetCurrentContext();    
  552.     
  553.     if (!r || NXIntersectsRect(r, &bounds))
  554.     {
  555.         setGraphicState(gParms, &parms, format);
  556.         makeRedBook(&path, format);
  557.         if (parms.path_type == FILL)
  558.         {
  559.             if (format == ABBR)
  560.                 PSWFill();
  561.             else if (format == BOT)
  562.                 DPSPrintf(ctxt, "\222\102");    
  563.             else
  564.                 PSfill();
  565.         }
  566.         else
  567.         {
  568.             if (format == ABBR)
  569.                 PSWStroke();
  570.             else if (format == BOT)
  571.                 DPSPrintf(ctxt, "\222\247");    
  572.             else
  573.                 PSstroke();
  574.         }
  575.     }
  576.  
  577.     return self;
  578. }
  579.  
  580. @end
  581.  
  582.